home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / comm2 / sndmlrxd.lzh / SendMail.rx
Text File  |  1995-12-01  |  14KB  |  282 lines

  1. /* filename: SendMail.rx                                                    */
  2. /*  version: 1.6     30 Sep 95                                              */
  3. /*  purpose: take input file in Internet RFC822 (e-mail) format and convert */
  4. /*           it into .txt and .wrk files for delivery via an SMTP client    */
  5. /*   syntax: (rx) SendMail <[input file specs]                              */
  6. /*    notes: while this program can be invoked manually, it is intended to  */
  7. /*           be called by AmigaELM as a replacement for other SendMail      */
  8. /*           programs                                                       */
  9. /*   author: Jim Dutton                                                     */
  10. /*           jimd@slip106.termserv.siu.edu                                  */
  11. /*           ca0008@siucvmb.siu.edu                                         */
  12. /* comments: Inspired by Sendmail.rx version 19931205 by Dan Rowan          */
  13. /*                                                                          */
  14. /*           To invoke from AmigaELM, add/modify the "Sendmail"/"Rmail"     */
  15. /*           configuration parameters similar to (using your own directory) */
  16. /*           in the uulib/.elm/elmrc file:                                  */
  17. /*                                                                          */
  18. /*                    SendMail rexxc:rx tcpip:sendmail.rx <$MSG             */
  19. /*                    RMail rexxc:rx tcpip:sendmail.rx <$MSG $TO            */
  20. /*                                                                          */
  21. /*           Some SMTP clients (eg; AmigaNOS) are not able to deal with MX  */
  22. /*           records (or target hosts which do not sport an SMTP server and */
  23. /*           require a seperate mail host to receive mail); an ARexx clip   */
  24. /*           list, needMXlist, is used to find which known hosts use an MX  */
  25. /*           record; another ARexx clip list is used to provide a known mail*/
  26. /*           host which corresponds to the MX record for the original target*/
  27. /*           host, and is called "useMXlist"; both of these lists are built */
  28. /*           and maintained manually by the user via the ARexx RXSET command*/
  29. /*                                                                          */
  30. /*           For example:                                                   */
  31. /*           RXSET needMXlist gwalter.demon.co.uk ppp11.llc.org aston.ac.uk */
  32. /*           RXSET useMXlist post.demon.co.uk biko.llc.org email.aston.ac.uk*/
  33. /*                                                                          */
  34. /*           There is a simple one-to-one correspondance between a known    */
  35. /*           host in the needMXlist and the useMXlist. You will need access */
  36. /*           to something like the NSLOOKUP program to find out the MX      */
  37. /*           record(s) associated with a given host, or you will need to    */
  38. /*           find a Domain Name Server related person who can find out that */
  39. /*           information for you.                                           */
  40. /*                                                                          */
  41. /*           You will need to change the value of the DefaultMailer variable*/
  42. /*           to the host name of a "smart(er)" mail (SMTP) server which can */
  43. /*           resolve host names that your SMTP client cannot; this should be*/
  44. /*           an SMTP server (gateway) within your existing domain/network   */
  45. /*                                                                          */
  46. /*           This SendMail program will process carbon copies and blind     */
  47. /*           carbon copies, but the keywords MUST be spelled correctly (see */
  48. /*           Select clause below), and begin on seperate lines              */
  49. /*                                                                          */
  50. /*           This program also allows MULTIPLE To:, Cc:, or Bcc: targets IF */
  51. /*           each target is immediately followed by a comma (except for the */
  52. /*           LAST target, of course) (eg; <target1>, <target2>)             */
  53. /*                                                                          */
  54. /*           To:, Cc:, and Bcc: target lists may cover more than one line IF*/
  55. /*           each line (but the last one) is terminated with a comma        */
  56. /*                                                                          */
  57. /*           A log file is maintained for every note that is processed. A   */
  58. /*           real sample log entry is:                                      */
  59. /*                                                                          */
  60. /* 22 Nov 1994 19:54:23 To: majordomo@NetBSD.ORG Subject: lists             */
  61. /*                                                                          */
  62. /*           You should modify the path for this log file to conform to your*/
  63. /*           system (set in variable MailLogFile below)                     */
  64. /*                                                                          */
  65. /*           The path for the SMTP client's mail queue on your system should*/
  66. /*           be verified against the MQueue variable below                  */
  67. /*                                                                          */
  68. /*           A working (temporary) copy of the note to be sent is kept on   */
  69. /*           the T: device                                                  */
  70. /*                                                                          */
  71. /*           This SendMail program is by NO means, exhaustive               */
  72. /*                                                                          */
  73. /* V1.5 changes ...                                                         */
  74. /* 1) use ENV:SMTPHOST for default (upstream/"smart") SMTP server/host      */
  75. /* 2) allow for multiple MX lists                                           */
  76. /*                                                                          */
  77. /* V1.6 changes ...                                                         */
  78. /* 1) add support for newsgroup articles (identified by a To: field with a  */
  79. /*    target of <newsgroup name> [ie; no "@" sign]) which inserts NNTP      */
  80. /*    header records and puts the 'note' in the 'news directory',           */
  81. /*    NNTPqueue, which is where AmigaNOS NNTP client looks for news items   */
  82. /*    to post (note: for some unknown reason, AmigaNOS appears to post only */
  83. /*    one note during each NNTP session ???)                                */
  84. /* 2) add generated MSGID to log file entry                                 */
  85. /* 3) added messgage REFID to NNTP articles (notes) log entries such as     */
  86. /*                                                                          */
  87. /* 30 Nov 1995 01:16:47 [30621] To: comp.mail.misc Subject: Re: pop3        */
  88. /*     server for VM/ESA <21b0c6fb.927cc>                                   */
  89.  
  90. Address 'COMMAND'
  91. Call Initialize
  92. Call ProcessInput
  93. Call CreateMqueue
  94. Call CloseUp
  95. Exit
  96.  
  97.  
  98. CloseUp:
  99.   duh = open(seqfile,MQueue'/sequence.seq','W')
  100.   duh = writech(seqfile,seq);  duh = close(seqfile)
  101.   duh = close(STDERR); duh = close(maillog)
  102.   'Delete T:tempfile.txt QUIET'
  103.   If ~show("L","rexxsupport.library")  then  duh = addlib("rexxsupport.library",0,-30,0)
  104.   parse value statef("T:SendmailErrors") with . size .
  105.   If size = 0  then  'Delete T:SendmailErrors QUIET'  /* don't waste dir blocks */
  106. Return
  107.  
  108.  
  109. Initialize:
  110.   If open(smtphost,"ENV:smtphost","R")  then
  111.      Do; DefaultMailer = strip(readln(smtphost)); duh = close(smtphost); End
  112.   Else
  113.      Do
  114.         duh = open(reminder,"CON:1/1/460/60/SendMail_Error/close")
  115.         duh = writeln(reminder,"*** Required ENV:smtphost not found ***")
  116.         duh = writeln(reminder, " "); duh = writech(reminder,"Press Enter to quit ...")
  117.         duh = readln(reminder);  foo = close(reminder);  Exit 28
  118.      End
  119.  
  120.   MailLogFile = "TCPIP:Logs/Mail.log";  isNetNews = no
  121.   MQueue = "TCPIP:spool/mqueue";  NNTPqueue = "TCPIP:Spool/News"
  122.   EndOfHeaders = no;  ReturnTrip = no;  TargetNum = 0;  tabchar = '09'x
  123.  
  124.   If ~open(seqfile,MQueue'/sequence.seq','R') then
  125.     Do; say "***Can't open sequence.seq file, aborting!"; Exit 32; End
  126.   seq = readln(seqfile); duh = close(seqfile)
  127.  
  128.   numMXlists = getclip("numMXlists")    /* number of MX lists to parse */
  129.   If ~datatype(numMXlists,"WHOLE")  then  numMXlists = 0
  130.   Else
  131.     Do i = 1 to numMXlists
  132.       needMXlist.i = getclip("needMXlist."i);  useMXlist.i = getclip("useMXlist."I)
  133.       upper needMXlist.i useMXlist.i
  134.     End
  135.  
  136.   If open(timezone,'ENV:TZ','R') then;  Do; tz=left(readln(timezone),3); duh = close(timezone); End
  137.   Else  tz = "GMT"
  138.  
  139.   If ~open(maillog,MailLogFile,"A")  then  duh = open(maillog,MailLogFile,"W")
  140.   duh = open(STDERR,"T:SendmailErrors","W"); duh = open(tempfile,"T:tempfile.txt","W")
  141.   duh = writeln(tempfile,'Date: '|| left(date('W'),3) ||', '|| date() ||' '|| time()||' '||tz)
  142. Return
  143.  
  144.  
  145. ProcessInput:
  146.   Do while EndOfHeaders = no
  147.     inline = strip(readln(STDIN))
  148.     If substr(inline,1,5) ~= "Bcc: "  then   duh = writeln(tempfile,inline)
  149.     Select
  150.         When  substr(inline,1,6) = "From: "     then  Call  ProcessFromLine
  151.         When  substr(inline,1,4) = "To: "       then  Call  ProcessToLines
  152.         When  substr(inline,1,4) = "Cc: "       then  Call  ProcessToLines
  153.         When  substr(inline,1,9) = "Subject: "  then  Call  ProcessSubjectLine
  154.         When  substr(inline,1,5) = "Bcc: "      then  Call  ProcessToLines
  155.         When  ReturnTrip        ~= no           Then  Interpret "Call" ReturnTrip
  156.         Otherwise;              If inline = ""  then  EndOfHeaders = yes
  157.     End
  158.   End
  159.  
  160.   Do while ~eof(STDIN);  duh = writeln(tempfile,readln(STDIN));  End
  161.     If isNetNews = yes  then duh = writeln(tempfile,".")
  162.   duh = close(STDIN);  duh = close(tempfile)
  163. Return
  164.  
  165.  
  166. ProcessFromLine:
  167.   If pos("<",inline) > 0  then   parse var inline "<"sendinguser">"
  168.   Else parse var inline . sendinguser .
  169. Return
  170.  
  171.  
  172. ProcessSubjectLine:
  173.     subjline = inline
  174.     If isNetNews = yes  then  Call  Rewrite_TempFile
  175. Return
  176.  
  177.  
  178. Rewrite_TempFile:
  179.     duh = close(tempfile)
  180.     'Rename from T:TempFile.Txt to T:TempFile.Hdrs QUIET'
  181.     duh = open(hdrsfile,"T:TempFile.Hdrs","R")
  182.     duh = open(tempfile,"T:TempFile.Txt","W")
  183.     dateline = strip(readln(hdrsfile)); fromline = strip(readln(hdrsfile))
  184.     parse value readln(hdrsfile) with "<"msgid"-" .
  185.     parse value readln(hdrsfile) with .  newsgroup .
  186.     subjectline = strip(readln(hdrsfile)); duh = close(hdrsfile)
  187.  
  188.     duh = writeln(tempfile,"Path: slip106.termserv.siu.edu")
  189.     duh = writeln(tempfile,fromline); duh = writeln(tempfile,"Newsgroups:" newsgroup)
  190.     duh = writeln(tempfile,subjectline)
  191.     duh = writeln(tempfile,"Message-Id: <"msgid"@slip106.termserv.siu.edu>") 
  192.     duh = writeln(tempfile,dateline)
  193.     duh = writeln(tempfile,"Sender: NNTP@slip106.termserv.siu.edu")
  194.     duh = writeln(tempfile,"Reply-To: jimd@slip106.termserv.siu.edu")
  195.     duh = writeln(tempfile,"Organization: Southern Illinois University")
  196.     duh = writeln(tempfile,"Comment: AmigaNOS v2.9p")
  197.     'Delete T:TempFile.Hdrs Quiet'
  198. Return
  199.  
  200.  
  201. ProcessToLines:
  202.   If pos(',',inline) > 0  then  /* split off multiple address fields */
  203.     Do
  204.     ReturnTrip = "ProcessToLines"; parse var inline inline","
  205.     End
  206.   Else  ReturnTrip = no
  207.  
  208.   TargetNum = TargetNum + 1;  ToLine.TargetNum = inline
  209.   Select
  210.     When pos("<",inline) > 0  then   parse var inline "<"targetuser">"
  211.     When pos("(",inline) > 0  then
  212.             Do
  213.               parse var inline before"(".")"after;  before = strip(before)
  214.               If before ~= ""  then  targetuser = before
  215.               Else targetuser = after
  216.  
  217.               If pos(":",targetuser) > 0  then  targetuser = subword(targetuser,2)
  218.               Else
  219.               If substr(targetuser,1,1) = tabchar  then  parse var targetuser +1 targetuser
  220.             End
  221.     When substr(inline,1,1) = tabchar  then   parse var inline +1 targetuser
  222.     Otherwise;    targetuser = subword(inline,2)
  223.   End
  224.  
  225.     /* determine if targethost is a newsgroup */
  226.     If (pos("@",targetuser) = 0) & (pos(".",targetuser) > 0)  then
  227.         Do; isNetNews = yes; routinghost = ""; Return;  End
  228.  
  229.   /* determine initial host to route mail to */
  230.   If pos("%",targetuser) > 0  then
  231.     Do
  232.       parse var targetuser userid"%"userhost"@"routinghost .
  233.       targetuser = userid"@"userhost
  234.     End
  235.   Else  parse var targetuser"@"routinghost .
  236.  
  237.   /* check for known hosts who require an (alternative) MX host */
  238.   If numMXlists > 0  then
  239.     Do
  240.        uppered_routinghost = routinghost;  upper uppered_routinghost
  241.        Do i = 1 to numMXlists
  242.          loc = find(needMXlist.i,uppered_routinghost)
  243.          If loc > 0  then  routinghost = word(useMXlist.i,loc)
  244.        End
  245.     End
  246.  
  247.   /* check for nasty UUCP addresses and convert */
  248.   upper inline
  249.   If pos("UUCP",inline) > 0  then
  250.     Do
  251.        routinghost = DefaultMailer; parse var targethost lhs"@"rhs".uucp" .
  252.        targetuser = lhs"%"rhs"@uunet.uu.net"
  253.     End
  254.  
  255.   TargetUser.TargetNum = targetuser;  RoutingHost.TargetNum = routinghost
  256. Return
  257.  
  258.  
  259. CreateMqueue:
  260.   Do i = 1 to TargetNum
  261.     seq = seq + 1
  262.  
  263.         If isNetNews = no  then
  264.             Do
  265.             duh = writeln(maillog,date() time() "["seq"]" ToLine.i subjline)
  266.             duh = open(mailwrk,MQueue'/'seq'.wrk','W')
  267.             duh = writeln(mailwrk,RoutingHost.i); duh = writeln(mailwrk,sendinguser)
  268.             duh = writeln(mailwrk,TargetUser.i);  duh = close(mailwrk)
  269.             'COPY T:tempfile.txt TO' MQueue'/'seq'.txt'
  270.             End
  271.         Else
  272.             Do
  273.             duh = writeln(maillog,date() time() "["seq"]" ToLine.i subjline" <"msgid">")
  274.             duh = open(mailwrk,NNTPqueue'/'seq'.wrk','W')
  275.                 duh = writeln(mailwrk,newsgroup)
  276.                 duh = writeln(mailwrk,"<"seq"@slip106.termserv.siu.edu>")
  277.                 duh = close(mailwrk)
  278.             'COPY T:tempfile.txt TO' NNTPqueue'/'seq'.txt'
  279.             End
  280.   End
  281. Return
  282.